<script setup>
import {
  ref,
  computed,
  watch,
  nextTick,
  onMounted,
  reactive,
  onUnmounted,
  createVNode,
} from "vue";
import request from "@/common/utils/request";
import {
  QuestionCircleOutlined,
  PlayCircleOutlined,
  PauseCircleOutlined,
  FolderOutlined,
  SaveOutlined,
  FontColorsOutlined,
  DeleteOutlined,
  SwapOutlined,
  UnorderedListOutlined,
  CloudUploadOutlined,
  EyeOutlined,
  InfoCircleOutlined,
  ExclamationCircleOutlined,
  CustomerServiceOutlined,
  RedoOutlined,
  EllipsisOutlined
} from "@ant-design/icons-vue";
import { Form, message, Empty, Modal } from "ant-design-vue";
const useForm = Form.useForm;
import { useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
import utils from '@/common/utils/utils'
import { debounce } from "lodash";
import { getUserInfo } from '@/common/utils/storage.js';
import { syncVideo } from "@/common/utils/api/userApi.js";


const store = useStore();

import notTextSpeech from "@/views/shotstack/CreationCenter/components/notTextSpeech.vue";
import AIExpansion from "@/views/shotstack/MatrixMarketing/modules/AIExpansion.vue";

import AudioPlayer from "@/views/shotstack/components/AudioPlayer/index.vue";

// 文案仿写
import TextImitationDialog from "@/views/shotstack/components/TextImitationDialog/index.vue";

// 素材库
import ChooseMaterial from "@/views/shotstack/EditingCenter/modules/bottomSet/components/chooseMaterial.vue";
// 文案库组件
import CopyLibraryModal from "@/components/AddTextModal/CopyLibraryModal.vue";
// 音色组件
import AudioSelection from "@/views/shotstack/MixedCutPlatforms/mixedCutCreat/components/Component/AudioSelection.vue";
// 视频文件
import MaterialsModule from "@/views/shotstack/components/MaterialsModule/index.vue";
const materials = ref(null);
// 消耗提示弹窗
// import Consumptiontime from "@/views/shotstack/components/dialogComponent/Consumptiontime.vue";
// 确定合成之后的提示弹窗
import creatNextDialog from "./Components/creatNextDialog.vue";
const creatNextDialogRef = ref(null);
// 保存到素材库
// import MaterialsModule from '@/views/shotstack/components/MaterialsModule/materialLibraryModal.vue'
// 确定合成选择模型弹窗
// import creatTypeDialog from "./Components/creatTypeDialog.vue";
// const creatTypeDialogRef = ref(null);

// 试听音频弹窗
import listenVoiceDialog from "@/views/shotstack/components/dialogComponent/listenVoiceDialog.vue";
const listenVoiceDialogRef = ref(null);

// 数字人字幕生成组件
import subtitleCreatDialog from './Components/subtitleCreatDialog.vue'
const subtitleCreatDialogRef = ref()

// 数字人字幕生成列表
import subtitleCreatList from './Components/subtitleCreatList.vue'
const subtitleCreatListRef = ref()

// 充值弹窗
import vipModal from '@/socialMedia/Vip/vipModal.vue'
const vipModalRef = ref(null)

// 富文本
import editor from './Components/editor/index.vue'
const editorRef = ref()

const route = useRoute();
const router = useRouter();

// 音色类型 为2(火山引擎) 的时候 隐藏标签控制按钮
// 0 - 腾讯云, 1 - 阿里云, 2 - 火山引擎
const hiddenSSML = 999

// const modal_List = ref([
//   {
//     label: "普通模型",
//     value: "ov4_2",
//   },
//   {
//     label: "高级模型",
//     value: "ov4_7",
//   },
// ]);

const maxLen = 2000

const state = reactive({
  checked: false,
  // 文本驱动或语音驱动
  activeKey: "1",
  videoType: "1",
  // 素材库开关
  visible: false,
  // 选择的音频素材
  audioData: null,
  // 默认音频暂停状态
  voiceState: false,
  loading: false,

  resetData: {},
  text: "",
  // 音频获取轮询接口
  indicator: false,
  simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
  currentSaveData: {},
  saveVisible: false,
  checked_num: 0,
  splitNum: 0,
  activeKeyTab: "1",
  columns: [
    {
      title: "任务ID",
      dataIndex: "id",
      key: "id",
      width: 80,
    },
    {
      title: "任务名称",
      dataIndex: "name",
      key: "name",
      width: 200,
    },
    {
      title: "任务ID",
      dataIndex: "speaker_id",
      key: "speaker_id",
      width: 100,
    },
    {
      title: "任务状态",
      dataIndex: "status_txt",
      key: "status_txt",
      width: 100,
    },
    {
      title: "音频地址",
      dataIndex: "audio_url",
      key: "audio_url",
      width: 100,
      align: "center",
    },
    {
      title: "视频地址",
      dataIndex: "video_url",
      key: "video_url",
    },
    {
      title: "更新时间",
      dataIndex: "updated_at",
      key: "updated_at",
    },
    {
      title: "导出",
      dataIndex: "edit",
      key: "edit",
    },
  ],
  dataSource: [],
  videoListLoading: false,
  total: 0,
  page: 1,
  pageSize: 20,

  // 文本驱动的时长
  text_useTime: 0,
  // 语音驱动的时长
  audio_useTime: 0,

  // 列表筛选, 状态
  status: {},
  // 模型
  model_type: {},

  // 筛选数据
  serchData: {},
  serchValue: {},
  // 筛选状态
  time: [],
  start_time: "",
  end_time: "",
  // 保存到素材库开关
  MaterialsModule: false,
  // 保存到素材库的内容
  materialData: {
    material_url: "",
    autoName: "",
  },
  // 保存到成片库: true; 保存到素材库:false
  isFlaking: false,
  // 选择数字人列表
  recordSerchData: {
    page: 1,
    pageSize: 20,
    total: 0,
    // 最后一页
    last_page: 1,
  },
  usenumber: "1",

  // 扣费规则展示
  deductionRuleText: '',

  volume: "",
  speed: "",
  emotion_intensity: "",

  // 合成记录, 页签key
  compoundTabKey:'数字人合成',

  // 视频预览弹窗开关 和链接存放
  viewVisible: false,
  videoUrl: '',

  // 富文本内容
  editorData:null,
  // 获取音频的 标签内容
  ssml:'',

  // 公共数字人 或 自建数字人
  selectHumanKey:'1'
});

const modelRef = reactive({
  name: "",
  audio_url: [],
  folder_id: undefined,
  // 选择的生成模型 ov5
  type: "ov4",
  // 选择的线路
  line_type: "7",
  // modal: null, //模型选择
  uniqueId: "",
  // 是否 有 公共数字人
  has_public_digital_human:false
});

// 视频弹窗开关
const vipVisible = ref(false)
const voice_config = ref({})

const old_config = ref({})

onMounted(() => {
  getStates();
  // 获取扣费规则
  deductionRule()
  // 获取音色的配置数据
  Promise.all([
    store.dispatch("videoMixCut/getDefaultVoiceData"),
    store.dispatch("videoMixCut/getRequestVoiceData"),
  ]).then((res) => {
    // 默认的音色数据
    const defaultVoiceData = store.state.videoMixCut.defaultVoiceData;
    voice_config.value = store.state.videoMixCut.voice_config;
    //  old_config.value = store.state.videoMixCut.voice_config;

    // 默认的音色配置
    const data = {
      emotion_intensity: voice_config.value.intensity.default, //情感程度
      speed: voice_config.value.speed.default, // 语速
      volume: voice_config.value.volume.default, // 音量
      emotion_category: "neutral", // 预期情感类型
      ...defaultVoiceData
    };
    // 初始赋值
    state.resetData = data
    console.log(state.resetData, '初始值');
  });
});



// 推荐的默认音频配置
const volcengine_config = computed(() => {
  return store.state.videoMixCut.volcengine_config;
});

// 获取扣费规则
const deductionRule = async () => {
  const res = await utils.consumptionPointRule()
  console.log(res, '扣费规则');
  const find = res.result.content.find(ele => ele.labelkey == "digital_human_video_point")

  find && (state.deductionRuleText = `${find?.label} ${find?.value} (${find?.desc})`)
}

// const notVoiceNumDialogRef = ref(null);

const getStates = async () => {
  const res = await request.get(
    "/work_ai",
    "/digital/human/required/information"
  );
  console.log(res, "筛选字段");
  state.serchData = res.result;
  // 搜索框使用 需要删除 humanStatus
  res?.result?.humanStatus && delete res.result.humanStatus;

  console.log(state.serchData, "state.serchData");

  for (let key in res.result) {
    const item = state.serchData[key];
    if (item.type == "select") {
      item.select.unshift({
        label: key == "type" ? "全部模型" : "全部状态",
        value: "all",
      });
      state.serchValue[key] = "all";
    } else if (item.type == "text") {
      state.serchValue[key] = "";
    }
  }
};
// 选择日期发生变化
const timeChange = (value, model) => {
  console.log(model, "时间变化");
  state.start_time = model[0];
  state.end_time = model[1];
  // // 日期被设为空值, 重新获取列表数据
  getHumanVideoList();
};

// 根据选择的tab栏, 决定应用的使用的时长
const useTime = computed(() => {
  return state.activeKey == "1" ? state.text_useTime : state.audio_useTime;
});

const formState = reactive({
  value: "",
  value2: "",
});

//删除所选音频
const delVoice = () => {
  state.audioData = null;
  modelRef.audio_url = "";
};

const voice = ref(null);
const playVoice = () => {
  if (voice.value) {
    if (voice.value.paused) {
      voice.value.play(); // 如果音频是暂停的，则播放
      state.voiceState = true;
    } else {
      voice.value.pause(); // 如果音频正在播放，则暂停
      state.voiceState = false;
    }
  }
};

// 音频开始回调
const onPlayChange = () => {
  console.log("开始");
  state.voiceState = true;
};

// 音频暂停回调
const onPauseChange = () => {
  console.log("暂停");
  state.voiceState = false;
};

// 音频结束回调
const endedChange = () => {
  console.log("结束");
  state.voiceState = false;
};

// 素材库选择音频回调
const closeChooseMaterial = (data) => {
  console.log(data, "素材");
  if (data) {
    state.audioData = data;
    modelRef.audio_url = data.material_url;
    modelRef.merchant_folder_statck_multimedia_id = data.id;
    // 存放使用时长
    state.audio_useTime = data.material_duration / 1000;
    let durationInSeconds = data.material_duration / 1000;
    let editCount = Math.ceil(durationInSeconds);
    state.usenumber = Math.max(editCount, 1);
  }
  state.visible = false;
};

const checkboxChange = (params) => {
  const {id, key} = params
  getChecked(id, key);
};

const checkedChange = (params) => {
  const {id, key} = params
  getChecked(id, key);
};

// Checked只能选择一个
const getChecked = (id, key) => {
  if (key == '公共') {
    humanRecordList.value.forEach((item) => {
      item.checked = false;
    });
    humanPublicList.value.forEach(item => {
      if (item.id == id) {
        item.checked = true;
      } else {
        item.checked = false;
      }
    })
  } else {
    humanPublicList.value.forEach((item) => {
      item.checked = false;
    });
    humanRecordList.value.forEach(item => {
      if (item.id == id) {
        item.checked = true;
      } else {
        item.checked = false;
      }
    })
  }
}


const rulesRef = reactive({
  name: [
    {
      required: true,
      message: "请输入视频合成名称",
    },
  ],
  audio_url: [
    {
      required: false,
      message: "请选择音频文件",
    },
  ],
  // modal: [
  //   {
  //     required: true,
  //     message: "请选择模型",
  //   },
  // ],
});
const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef);

let copyLibraryModal = ref(null); //素材库导入组件实例

// 文案库导入
const importingLibrary = () => {
  if (state.indicator) {
    return;
  }
  copyLibraryModal.value && copyLibraryModal.value.showModal();
};

let TextImitationDialogRef = ref(null); //素材库导入组件实例

// 文案仿写导入
const importingTextImiton = () => {
  if (state.indicator) {
    return;
  }
  TextImitationDialogRef.value && TextImitationDialogRef.value.showModal();
};

const getTextArr = (list) => {
  const text = list[0]?.content
  // 赋值富文本
  text && updateEditor({text})
  TextImitationDialogRef.value.closeModal()
}

let aiExpansionRef = ref(null); 

// AI扩写
const addAIExpansion = () => {
  aiExpansionRef.value && aiExpansionRef.value.showModal({text:state.text});
};

const onConfirmAIExpansion = (arr) => {
  aiExpansionRef.value && aiExpansionRef.value.cancelClick();
  const text = arr[0]?.text
  // 赋值富文本
  updateEditor({text})
}


const AISpinging = ref(false)

// AI改写
const handleAIRequest = async (param) => {
  const { clickType } = param

// 获取富文本内容, 并将state.text 同步的方法
  synchronizeText()
  
  if (state.text == "") {
    return message.error("请输入内容");
  }
  try {
    // 查看用户的点数是否足够消耗
    await utils.aiTextGet()
    try {
      // 消耗规则
      const rule = await utils.consumptionPointRule()
      // 获取提示
      const content = utils.ruleTips({ res: rule, key: "ai_text_point" })
      // 弹出提示
      await utils.md({ content })
      // 弹窗确认消耗
    } catch (error) {
      return
    }
  } catch (error) {
    // 打开充值, 接着打开点数购买
    vipVisible.value = true
    vipModalRef.value && vipModalRef.value.openBuyVisible()
    return
  }

  const params = {
    // 0-扩写AIExpand 1-改写AIRewriting
    is_text_rewrite: clickType == "AIRewriting" ? 1 : 0,
    ai_keyword_id: "",
    ai_keyword_group_id: "",
    content: state.text,
    ai_type: "desc", 
    platform: "", 
  };
   AISpinging.value = true;

     try {
        const successRes = await request.post(
          "work_ai",
          "/user/filmrelease/ai/generate_title",
          params
        );

        if (!successRes || !successRes.result) {
          AISpinging.value = false;
          return message.error("AI生成失败，状态id丢失");
        }

        const timerId = setInterval(async () => {
          try {
            const statusRes = await request.get(
              "/work_ai",
              "/user/filmrelease/ai/generate_title/status",
              { task_id: successRes.result }
            );
            if (
              statusRes.result.status === "success" ||
              statusRes.result.status === "error"
            ) {

              if (statusRes.result.data.length) {
              // const originalString = statusRes.result.data[0]; 
              // state.text = originalString.substring(originalString.indexOf('\n') + 1);
                const text = statusRes.result.data[0]
                updateEditor({text})
              }
              clearInterval(timerId);
              AISpinging.value = false;
            }
          } catch (statusErr) {
            AISpinging.value = false;
            clearInterval(timerId);
          }
        }, 1000);


      } catch (errorRes) {
        console.log(errorRes);
      }

}

// 文案库导入成功回调
const audioLItemImportSuccess = (data) => {
  if (data.length) {
    const text = data[0].material_content
    // 赋值富文本
    updateEditor({text})
  }
};

// 音色选择
const audioSelection = ref(null);
const voiceSelector = () => {
  if (state.indicator) {
    return;
  }

  audioSelection.value.showModal();
};

// 选择 音色回调
const resetDataChange = (data) => {
  const { voiceDataItem, config } = data || {};
  // 如果音色id不一样, 则清空音频
  // state.resetData?.timbre_id != voiceDataItem?.id && (modelRef.audio_url = "");
  modelRef.audio_url = ""
  state.resetData = { ...voiceDataItem, ...config };
  console.log(data, "选择的音色");

  if (state.resetData?.voice_type == hiddenSSML) { 
    message.warning('该音色暂不支持文本标记, 已为您自动去除', 3)
    // 更新并获取 当前富文本的文案
    synchronizeText()
    // 清空富文本的所有标记
    updateEditor({text:state.text})
  }
};

// 音色默认列表
// const getVoiceList = () => {
//   request
//     .get("/work_ai", "/user/shotstack/voice/list", { category: "common" })
//     .then((res) => {
//       // debugger
//       const item = res.result[0].item[0]
//       console.log(item,'即将赋值的item');
//       // state.resetData = JSON.parse(JSON.stringify(item))
//       console.log(state.resetData,'默认的音色');
//     });
// };

const activeKeyChange = (e) => {
  if (e == 2) {
    rulesRef.audio_url[0].required = true;
  } else {
    rulesRef.audio_url[0].required = false;
  }
};


const onCancel = () => {
  state.saveVisible = false;
};

// 确认保存, 打开文件夹选择
const isSubmit = () => {
  // const underscoreIndex = modelRef.modal.indexOf("_"); // 找到下划线的位置

  // const beforeUnderscore = modelRef.modal.slice(0, underscoreIndex); // 获取下划线前的部分
  // const afterUnderscore = modelRef.modal.slice(underscoreIndex + 1); // 获取下划线后的部分

  // modelRef.type = beforeUnderscore;
  // modelRef.line_type = afterUnderscore;
  console.log(modelRef, "提交的参数123123");
  videoAdd(modelRef);
};

// 获取数字人 消耗提示
const getHumanConfig = () => {
  let usernumbers = state.usenumber;
  // 判断 普通 / 高级 模式
  // if (modelRef.modal == "ov4_7") {
  //   usernumbers = state.usenumber * 2;
  // } else {
  //   usernumbers = state.usenumber;
  // }

    return new Promise(async(resolve, reject) => {      
      try {
        const res = await utils.humanConfigGet({ number: usernumbers })
        // 查询积分, 积分不足则走不到这一步
        // 获取积分消耗提示内容
        const content = utils.useText(res)
        try {
          // 确认消耗
          await utils.kd({ content,res })
          resolve(res)
        } catch (error) {
          reject(error)
        }
      } catch (error) {
        // 打开充值, 接着打开点数购买
        vipVisible.value = true
        vipModalRef.value && vipModalRef.value.openBuyVisible()
        reject(error)
        return
      }
    })
};

let textChange = "";
let ssmlData = "";
// 确定合成
// const creatTypeDialogSubmit = (type) => {
//   modelRef.type = type;
// };
// const creatTypeDialogSubmit = (type) => {
//   modelRef.type = type;
// };

const getuniqueId = async () => {
  const res = await request.get("/work_ai", "/user/platform/uniqueId")
  modelRef.uniqueId = res.uniqueId
}

const submitCreat = async () => {

  validate().then(async () => {

    // 1 - 自建  2 - 公共
    const filterArr = state.selectHumanKey == 1 ? humanRecordList.value : humanPublicList.value

    const find = filterArr.find(ele => ele.checked)
    modelRef.human_id = find?.id

    if (!modelRef.human_id) {
      message.warn("请选择数字人");
      return;
    }

    // 获取最新的富文本数据, 并同步
    synchronizeText()

    // return
    if (state.activeKey == "1") {
      if (!state.text) {
        message.warn("请输入文案");
        return;
      }
      if (state.indicator) {
        message.warn("音频合成中，请稍后...");
        return;
      }

    await getuniqueId()

      // await getHumanConfig()

      handleOk(state.editorData)
    } else {
      if (!state.audioData) return message.warn("请选择音频文件");
      
      await getHumanConfig()
      isSubmit()
    }
  });
};

 const debouncedsubmitCreat = debounce(submitCreat, 1000, {
   leading: true,
   trailing: false,
 });

let time = ref('')

const handleOk = async (editorData) => {
  // state.allTime = await getHumanConfig();
  // if (state.allTime <= 0) {
  //   // 此时打开弹窗, 避免后续消耗
  //   ConsumptiontimeRef.value.showModal({
  //     notAllTime: true,
  //   });
  //   return;
  // }
  // 判断是文案是否改变
  if (textChange == state.text.trim()
    && editorData?.textData?.ssml == ssmlData
  && modelRef.audio_url) {
    await getHumanConfig()
    isSubmit()
  } else {
    try {
      const res = await utils.textConfigGet({
        number: state.text.length
      })
      // 查询积分, 积分不足则走不到这一步
      // 获取积分消耗提示内容
      const content = utils.useText(res)
      // try {
        // 确认消耗
        // await utils.kd({ content,res })
      // } catch (error) {
      //   return
      // }
    } catch (error) {
      // 打开充值, 接着打开点数购买
      vipVisible.value = true
      vipModalRef.value && vipModalRef.value.openBuyVisible()
      return
    }
    let params = {
      // text: state.text,
      text: editorData?.textData?.ssml,
      speed:
        state.resetData.voice_type == 2
          ? state.resetData.recommendSpeed
          : state.resetData.speed,
      timbre_id: state.resetData.tone_id,
      volume: state.resetData.volume,
      emotion_category: state.resetData.emotion_category,
      emotion_intensity: state.resetData.emotion_intensity,
      id: state.resetData.id,
      category: state.resetData.category,
    };
    textChange = state.text;
    ssmlData = state.ssml;
    state.indicator = true;
    request
      .post("/work_ai", "/user/shotstack/textToVoice", params)
      .then((res) => {

        const getResFn = () => {
          return new Promise((resolve, reject) => {
            time.value = setTimeout(() => {
              request
                .get("/work_ai", "/user/shotstack/getVoice", {
                  task_id: res.result.task_id,
                  request_id: res.result.request_id || "",
                })
                .then(async(task) => {
                  if (task.result.Data?.ResultUrl?.length > 0) {
                    console.log(task,'音频回来的结果----------');
                
                modelRef.audio_url = task.result.Data.ResultUrl;
                    // 存放消耗的时长
                    state.text_useTime = task.result.duration;
                    let durationInSeconds = task.result.duration;
                    let editCount = Math.ceil(durationInSeconds);
                    state.usenumber = Math.max(editCount, 1);
                    state.indicator = false;
                    clearTimeout(time.value);
                    await getHumanConfig()
                    isSubmit()
                  } else {
                    await new Promise((resolveFn) => {
                      setTimeout(() => {
                        resolveFn()
                      },2000)
                    })
                    getResFn()
                  }
                })
                .catch((err) => {
                  clearTimeout(time.value);
                  state.indicator = false;
                });
            }, 1500);
          })
          
        }

        getResFn()

      });
  }
};

// 最终保存
const videoAdd = (modelRef) => {
  state.loading = true;
  // 数字人id
  // modelRef.human_id =
  //   humanRecordList.value.filter((item) => item.checked).map((v) => v.id)[0] ||
  //   [];

  // 如果是文本驱动, 删除素材id参数
  if (state.activeKey == "1") {
    delete modelRef.merchant_folder_statck_multimedia_id;
  }

  request
    .post("/work_ai", "/digital/human/video/add", modelRef)
    .then((res) => {
      if (res?.code && res.code != 1000) {
        throw new Error(res.msg);
      }
      state.loading = false;
      message.success("提交成功");
      creatNextDialogRef.value.showModal();
    })
    .catch((err) => {
      state.loading = false;
      message.error(err.message || "提交失败");
    });
};

// 弹窗倒计时结束
const timerOver = (mode) => {
  mode == "view" && (state.activeKeyTab = "2");
  creatNextDialogRef.value.closeModal("none");
};

// 预览视频 实例
const videoRef = ref()

//查看视频
const toviewVideo = (url) => {
  if (url) {
    state.videoUrl = url
  state.viewVisible = true
  }
};
// 关闭弹窗, 停止视频播放
watch(() => state.viewVisible, (nv, ov) => {
  if (!nv) {
    videoRef.value?.pause()
  }
})

const videoRequiredData = ref({});

const getHumanVideoRequired = () => {
  request.get("/work_ai", "/digital/human/video/required").then((res) => {
    videoRequiredData.value = res.result;
  });
};

const humanRecordList = ref([]);

// 数字人列表
const getHumanRecord = () => {
  const params = {
    page: state.recordSerchData.page,
    pageSize: state.recordSerchData.pageSize,
  };
  // /digital/human/record
  request
    .get("/work_ai", "/digital/human/record", params)
    .then((res) => {
      console.log(res, "列表数据");
      humanRecordList.value.push(...res.result.data);
      state.recordSerchData.total = res.result.total;
      state.recordSerchData.last_page = res.result.last_page;
      if (state.recordSerchData.page >= res.result.last_page) {
        notmore.value = true;
      }
      if (route.query.id) {
        const find = humanRecordList.value.find(
          (ele) => ele.id == route.query.id
        );
        if (find) {
          find.checked = true;
          find.disabled = false;
        }
      }
    })
    .catch((err) => {});
};

// 公共形象
const humanPublicList = ref([])

// 数字人公共形象
const getHumanPublicList = async () => {

  // 获取 workAi 系统配置 -- 用于判断选择素材 是否包含网络素材
  const list = await store.dispatch("getAiConfig")
  console.log(list, '有没有权限呢??');
  
  state.has_public_digital_human = !!list?.has_public_digital_human

  if (state.has_public_digital_human == true) {  
    const params = {}
    const res = await request.get("/work_ai", "/digital/human/public/list", params)
    console.log(res, '公共形象');
    humanPublicList.value = res.result??[]
 }

} 

// 触底加载
// 滚动条容器
const scrollBox = ref(null);
// 没有更多了
const notmore = ref(false);
const handleScroll = () => {
  if (
    scrollBox.value.scrollTop + scrollBox.value.clientHeight >=
    scrollBox.value.scrollHeight
  ) {
    // 触底时请求下一页数据
    const { last_page, page } = state.recordSerchData;
    if (page >= last_page) {
      notmore.value = true;
      return;
    }
    state.recordSerchData.page++;
    getHumanRecord();
  }
};

const goAIdigitalHuman = () => {
  router.push({
    name: "AIdigitalHuman",
    query: { type: "AIdigitalHumanCreatVideo" },
  });
};

const serchChange = () => {
  getHumanVideoList();
};

// 重置搜索状态
const resetSerch = () => {
  state.total = 0;
  state.page = 1;
  state.pageSize = 20;
  state.start_time = "";
  state.end_time = "";
  state.time = [];
  // 重置数据
  for (let key in state.serchData) {
    const item = state.serchData[key];
    if (item.type == "select") {
      state.serchValue[key] = "all";
    } else if (item.type == "text") {
      state.serchValue[key] = "";
    }
  }
  getHumanVideoList();
};

let timerId = ref(null);
// 合成记录列表
const getHumanVideoList = (data = { polling: false }) => {
  if (!data.polling) {
    state.videoListLoading = true;
  }
  if (timerId.value) {
    clearTimeout(timerId.value);
    timerId.value = null;
  }

  
  let params = {
    page: state.page,
    pageSize: state.pageSize,
    start_time: state.start_time,
    end_time: state.end_time,
  };
  
  for (let key in state.serchData) {
    const item = state.serchData[key];
    if (item.type != "url") {

      // 过滤出 select 中的全部选项
      if (item.type == "select" && state.serchValue[key] == "all") {
        params[key] = "";
      } else {
        params[key] = state.serchValue[key];
      }
    }
  }

  request
    .get("/work_ai", "/digital/human/video/list", params)
    .then((res) => {
      state.dataSource = res.result.data;
      state.total = res.result.total;
      state.videoListLoading = false;
      // 有status为以下状态的, 需要轮询
      const arr = [0, 1, 2];
      const undone = state.dataSource.some((ele) => {
        return arr.includes(ele.status);
      });

      if (undone) {
        timerId.value = setTimeout(() => {
          getHumanVideoList({ polling: true });
        }, 4000);
      }
    })
    .catch((err) => {
      state.videoListLoading = false;
    });
};

watch(
  () => state.activeKeyTab,
  (val) => {
    if (val == "2") {
      state.page = 1;
      state.pageSize = 20;
      getHumanVideoList();
    }
  }
);

const statusColor = (status) => {
  switch (status) {
    case 1:
      return "orange";
    case 2:
      return "blue";
    case 3:
      return "green";
    case 4:
      return "red";
    case 5:
      return "pink";
    case 6:
      return "purple";
    case 7:
      return "cyan";
  }
};

const init = () => {
  getHumanRecord();
  getHumanVideoRequired();
  // getVoiceList();

  // 获取公共数字人形象
  getHumanPublicList()

};


init();



const handleSave = async (item, type) => {
  state.saveItem = JSON.parse(JSON.stringify(item));
  if (type == "material") {
    // 保存到素材库
    state.isFlaking = false;
    state.saveVisible = true;
  } else if (type == "complete") {
    // 保存到成片
    state.isFlaking = true;
    state.saveVisible = true;
  } else {
    item.downloading = true;
    // 下载
    const response = await fetch(item.video_url); // 获取视频链接
    const blob = await response.blob(); // 将响应转为 Blob
    const url = window.URL.createObjectURL(blob); // 创建一个 blob URL

    const link = document.createElement("a");
    link.href = url; // 设置 href 为 blob URL
    link.download = "video.mp4"; // 可选，设置下载时的文件名
    document.body.appendChild(link);
    link.click(); // 模拟点击下载
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url); // 清理
    item.downloading = false;
  }
};

// 拿到选择的文件夹等信息
const selfRequest = async (data) => {
  console.log(data);
  const params = {
    digital_id: state.saveItem.id,
    merchant_folder_statck_id: data?.merchant_folder_statck_id,
    // 保存素材库 固定值为backend
    upload_from: state.isFlaking ? "" : "backend",
  };
  console.log(params, "接口参数");

  try {
    const res = await request.post(
      "/work_ai",
      "/user/shotstack/media/digital/save",
      params
    );
    if (res?.code && res.code != 1000) throw new Error(res.msg);
    console.log(res, "保存成功");
    message.success("保存成功");
  } catch (error) {
    message.error(error.message || "保存失败");
  } finally {
      materials.value.stopLoding();
      state.saveVisible = false;
  }
};

const listenVoice = (item) => {
  listenVoiceDialogRef.value &&
    listenVoiceDialogRef.value.showModal(item.audio_url);
};

const topUp = () => {
  vipVisible.value = true;
}

// 删除某项视频
const delItem = (data) => {
  Modal.confirm({
    title: "确定要删除该视频吗?",
    icon: createVNode(ExclamationCircleOutlined),
    okText: "确定",
    cancelText: "取消",
    onOk: async () => {
      try {
        const res = await request.del("/work_ai", "/digital/human/video/delete", { id: data.id });
        message.success('删除成功')
             getHumanVideoList();
        // 假设这里需要根据响应做进一步处理
      } catch (error) {
        // 错误处理
        console.error("删除失败:", error);
      }
    },
  });
};


// 生成字幕
const creatSubtitle = (item) => {
  console.log(item,'需要生成字幕的项目');
  subtitleCreatDialogRef.value?.open(item)
}

const playAutoClick = async () => {
  if (isResultUrl.value) {
  isPlay.value = !isPlay.value;
  playNum.value++;
  return;
}

// 非空校验
 if (!state.text) {
   message.warn("请输入文案");
   return;
 }
  // 扣点数
  try {
    const res = await utils.textConfigGet({
      number: state.text.length
    })
    const content = utils.useText(res)
    try {
      // 确认消耗
      await utils.kd({ content,res })
    } catch (error) {
      return
    }
  } catch (error) {
    // 打开充值, 接着打开点数购买
    vipVisible.value = true
    vipModalRef.value && vipModalRef.value.openBuyVisible()
    return
  }
  playOk()
}

const debouncedplayAutoClick = debounce(playAutoClick, 1000, {
  leading: true,
  trailing: false,
});


const isResultUrl = ref("")
const indicator = ref(false)
const isPlay = ref(false)
const voiceName = ref("")
const playNum = ref(0)
// 试听 (文本转语音)
const playOk = () => {


  let params = {
        text: state.text,
        speed: state.resetData.recommendSpeed,
        timbre_id: state.resetData.tone_id,
        volume: state.resetData.volume,
        emotion_category: state.resetData.emotion_category,
        emotion_intensity: state.resetData.emotion_intensity,
        id: state.resetData.id,
        category: state.resetData.category,
  };
   AISpinging.value = true;


  request
    .post("/work_ai", "/user/shotstack/textToVoice", params)
    .then((res) => {
          let tiem = setInterval(() => {
            request
              .get("/work_ai", "/user/shotstack/getVoice", {
                task_id: res.result.task_id,
                request_id: res.result.request_id || "",
              })
              .then((task) => {
                if (task.result?.Data?.ResultUrl) {
                  AISpinging.value = false;
                  isResultUrl.value = task.result.Data.ResultUrl;
                  indicator.value = false;
                  isPlay.value = true;
                  voiceName.value = res.result.voice_name;
                  clearInterval(tiem);
                }
              });
          }, 1500);
    });
}

const audioStatus = (status) => {
  console.log(status, '读完了  结束的时候触发dwdwdwdw');
    isPlay.value = false

}

const setAudio = () => {
  console.log('触发了 setAudio方法 ');
}


const handleInput = (e) => {
  console.log(e, '这是textarea的输入方法  _!!!!!!11123131312');
  if (isResultUrl.value) {
    isResultUrl.value = ""
  }
}

// 重置按钮相关
const resetState = () => {
  console.log( old_config.value,  '相关配置项6666688899999');
}

// 通知数字人字幕生成列表组件 更新
const openSubtitleCreat = () => {
  state.compoundTabKey = '数字人字幕生成'
  subtitleCreatListRef.value?.updateList()
}

watch(
  () => store.state.videoMixCut.voice_config,
  (val) => {
    if (val) {      
      // voice_config.value = val
      state.volume = val.volume?.default
      state.speed  = val.speed?.default
      state.emotion_intensity  = val.intensity?.default
    }
  },
  {
    immediate: true,
    deep: true
  }
);
watch(
  () =>  state.volume,
  (val) => {
    if (store.state.videoMixCut.voice_config.volume?.default !== val) {
      store.commit("videoMixCut/SET_VOLUME_DEFAULT", val);
    }
  }
);
watch(
  () =>  state.speed,
  (val) => {
    if (store.state.videoMixCut.voice_config.speed?.default !== val ) {
      store.commit("videoMixCut/SET_VOLUME_DEFAULT_SPEED", val);
    }
  }
);
watch(
  () =>  state.emotion_intensity,
  (val) => {
    if (store.state.videoMixCut.voice_config.intensity?.default !== val ) {
      store.commit("videoMixCut/SET_VOLUME_DEFAULT_INTENSITY", val);
    }
  }
);

// 获取富文本内容, 并将state.text 同步的方法
const synchronizeText = () => {
  const editorData = editorRef.value?.getContent()
    state.editorData = editorData
    state.text = editorData?.textData?.text || ''
    state.ssml = editorData?.textData?.ssml || ''
}

// 更新富文本内容 并将state.text 同步的方法
const updateEditor = (params) => {
  const { text = '' } = params
  let stringText = text || ''
  editorRef.value?.setContent(stringText)
  state.text = stringText
}

// 按钮loading
const queryResultLoading = ref(false)
// 手动查询数字人合成记录
const queryResult = async (item) => {
  queryResultLoading.value = true
  console.log(item, '要查询的item');
  console.log(state.serchData, '什么东西');
  const params = {
    id:item?.id
  }
  try {    
    const res = await request.get("/work_ai","/digital/human/video/result",params);
    const status = state.serchData.zstatus.select.find(ele => ele.value == res?.result?.status)
    console.log(res, '什么结果???');
    message.success(`（${item?.id}）的最新状态为:${status?.label}`)
  } finally {
    queryResultLoading.value = false
  }
}

const debounceQueryResult = debounce(queryResult, 400)

// 同步用户视频记录
const toSyncVideo = () => {
      const uid = getUserInfo()?.id;
      console.log(uid,'uid');
      AISpinging.value = true;
      syncVideo({
        uid: uid
      }).then(res => {
          console.log(res,'同步用户视频记录');
          if(res.errno === 0){
            message.success('同步成功');
            state.page = 1;
            state.pageSize = 20;
            getHumanVideoList();
            AISpinging.value = false;
          }else{
            AISpinging.value = false;
            message.error(res.msg);
            }
      }).catch(err => {
        message.error(err);
        AISpinging.value = false;
      })
    }

// 离开页面, 清除定时器
onUnmounted(() => {
  timerId.value && clearTimeout(timerId.value);
});
</script>

<template>
  <div class="AIdigitalHumanCreatVideo">
    <div style="display: flex;width: 100%;background-color: #fff; border-radius: 8px;justify-content: space-between;align-items: center;">
      <a-tabs style="padding: 0 0 10px 15px; background-color: #fff; border-radius: 8px"
      v-model:activeKey="state.activeKeyTab">
      <a-tab-pane key="1">
        <template #tab>
          <a-row>
            <a-col>
              <play-circle-outlined style="font-size: 20px" />
            </a-col>
            <a-col> 生成视频 </a-col>
          </a-row>
        </template>
      </a-tab-pane>
      <a-tab-pane key="2">
        <template #tab>
          <a-row>
            <a-col>
              <unordered-list-outlined style="font-size: 20px" />
            </a-col>
            <a-col> 合成记录 </a-col>
          </a-row>
        </template>
      </a-tab-pane>
    </a-tabs>
    <a-row v-if="state.activeKeyTab == '2'" @click="toSyncVideo" style="padding-right: 20px;cursor: pointer;">
            <!-- <a-col> 同步视频 </a-col> -->
          <a-button type="primary" :disabled="AISpinging">同步视频</a-button>
          
    </a-row>
    </div>
    
    <!-- 生成视频 -->
    <template v-if="state.activeKeyTab == '1'">
      <a-form layout="vertical" style="height: 100%; overflow: hidden; display: flex">
        <div class="content_box">
          <div class="left_box">
            <h2>选择数字人</h2>
            <a-tabs v-model:activeKey="state.selectHumanKey">
              <a-tab-pane key="1" tab="自建"></a-tab-pane>
              <a-tab-pane key="2" tab="公共" force-render v-if="state.has_public_digital_human"></a-tab-pane>
            </a-tabs>
            <div class="list_box" @scroll="handleScroll" ref="scrollBox">

              <!-- 自己创建的数字人形象 -->
              <template v-if="state.selectHumanKey == 1">
                <div class="list_item" v-for="item in humanRecordList" :key="item.id" @click="checkedChange({id:item.id, key:'自建'})">
                  <a-checkbox class="check_box" :disabled="item.disabled" v-model:checked="item.checked"
                    @change="checkboxChange({id:item.id, key:'自建'})" />
                  <template v-if="!item.url_image">
                    <video :src="item.video_url" style="height: 130px"></video>
                  </template>
                  <template v-else>
                    <img :src="item.url_image" style="height: 130px; width: auto" />
                  </template>
                  <PlayCircleOutlined class="icon_PlayCircleOutlined" @click.stop="toviewVideo(item.video_url)">
                  </PlayCircleOutlined>
                  <div class="mask-box mask_name">
                    <span class="is_span">
                      {{ item.name }}
                    </span>
                  </div>
                </div>
  
                <a-row class="empty-box" v-if="!humanRecordList.length">
                  <a-col>
                    <a-empty :image="state.simpleImage" style="margin: 0 auto" />
                  </a-col>
                  <a-col>
                    <div>您还没有数字人形象</div>
                    <a @click="goAIdigitalHuman">去创建</a>
                  </a-col>
                </a-row>
              </template>

              <!-- 数字人公共形象  -->
              <template v-else>
                <div class="list_item" v-for="item in humanPublicList" :key="item.id" @click="checkedChange({id:item.id, key:'公共'})">
                  <a-checkbox class="check_box"  v-model:checked="item.checked"
                    @change="checkboxChange({id:item.id, key:'公共'})" />
                  <template v-if="!item.url_image">
                    <video :src="item.video_url" style="height: 130px"></video>
                  </template>
                  <template v-else>
                    <img :src="item.url_image" style="height: 130px; width: auto" />
                  </template>
                  <PlayCircleOutlined class="icon_PlayCircleOutlined" @click.stop="toviewVideo(item.video_url)">
                  </PlayCircleOutlined>
                  <div class="mask-box mask_name">
                    <span class="is_span">
                      {{ item.name }}
                    </span>
                  </div>
                </div>
  
                <a-row class="empty-box" v-if="!humanPublicList.length">
                  <a-col>
                    <a-empty :image="state.simpleImage" style="margin: 0 auto" />
                  </a-col>
                  <a-col>
                    <div>暂无数字人形象</div>
                  </a-col>
                </a-row>
              </template>

            </div>

            <!-- 分页 :hideOnSinglePage="true" -->
            <!-- <a-pagination style="margin-top: 20px;" :showSizeChanger="true" @change="logPaginationChange"
              v-model:current="state.recordSerchData.page" v-model:pageSize="state.recordSerchData.pageSize"
              :total="state.recordSerchData.total" /> -->
          </div>
          <div class="right_box">
            <a-tabs v-model:activeKey="state.activeKey" centered @change="activeKeyChange">
              <a-tab-pane key="1" tab="文本驱动" style="height: 100%" />
              <a-tab-pane key="2" tab="语音驱动" :disabled="state.indicator" force-render style="height: 100%" />
            </a-tabs>
            <div class="tab_text">
              <div class="tab_text_left tab_video">
                <!-- <a-form-item label="模型选择" v-bind="validateInfos.modal">
                  <a-select placeholder="请选择模型" v-model:value="modelRef.modal" :options="modal_List" />
                </a-form-item> -->

                <a-form-item v-bind="validateInfos.name">
                  <template #label>
                    {{ videoRequiredData.name?.label }}
                    <a-tooltip>
                      <template #title>
                        {{ videoRequiredData.name.tip.join("") }}
                      </template>
                      <question-circle-outlined v-if="videoRequiredData.name?.tip" style="margin-left: 5px" />
                    </a-tooltip>
                  </template>
                  <a-input v-model:value="modelRef.name" :maxlength="videoRequiredData.name?.max"
                    :placeholder="'请输入' + videoRequiredData.name?.label" />
                </a-form-item>
                <!-- </div> -->
                <a-row align="middle" justify="space-between" style="width: 100%; margin-bottom: -8px"
                  v-if="state.activeKey == '1'">
                  <a-col>
                    <a-button type="link" @click.stop="importingLibrary" :disabled="AISpinging">文案库导入</a-button>
                    <a-button type="link" @click.stop="importingTextImiton" :disabled="AISpinging">文案仿写</a-button>
                    <a-button type="link" @click.stop="handleAIRequest({
                      clickType: 'AIExpand',
                    })" :disabled="AISpinging">
                      <cu-icon style="" type="icon-iconkuoxie"></cu-icon>AI扩写</a-button>
                    <a-button type="link" @click.stop="handleAIRequest({
                      clickType: 'AIRewriting',
                    })" :disabled="AISpinging">
                      <cu-icon style="" type="icon-AIgaixie"></cu-icon>
                      AI改写</a-button>
                  </a-col>
                  <a-col @click.stop>
                    选择音色：
                    <a-button @click.stop="voiceSelector" :disabled="AISpinging">
                      {{ state.resetData.name }}_{{
                      state.resetData.human_style
                      }}
                      <swap-outlined />
                    </a-button>

                    <a-popover v-if="false" :title="null" trigger="click">
                      <template #content>
 
                        <!-- 重置按钮 -->
                        <div class="yinse_vonfig">
                       <!-- <span  class="reset_btn" @click="resetState">
                         <RedoOutlined />
                       </span> -->



                          <div class="config_cart">
                          <span>音量 {{ state.volume  }}</span>
                          <div class="slider_box">
                           <span style="margin-right: 8px">{{voice_config.volume.min}}</span>
                           <a-slider class="slider" :min="voice_config.volume.min" :max="voice_config.volume.max" id="test"
                             :step="voice_config.volume.separate" v-model:value="state.volume" />
                           <span style="margin-left: 8px">{{ 100 }}</span>
                           </div>
                         </div>
                        <div class="config_cart">
                        <span>语速 {{ state.speed }}</span>
                        <div class="slider_box">
                          <span style="margin-right: 8px">{{
                            voice_config.speed.min
                            }}</span>
                          <a-slider class="slider" id="test" :min="voice_config.speed.min" :max="voice_config.speed.max"
                            :step="voice_config.speed.separate" v-model:value="state.speed" />
                          <span style="margin-left: 8px">{{
                            voice_config.speed.max
                            }}</span>
                        </div>
                      </div>
                      <div class="config_cart">
                        <span>情感 {{ state.emotion_intensity }}</span>
                        <div class="slider_box">
                          <span style="margin-right: 8px">{{
                            voice_config.intensity.min
                            }}</span>
                          <a-slider class="slider" id="test" :min="voice_config.intensity.min" :max="voice_config.intensity.max"
                            :step="voice_config.intensity.separate" v-model:value="state.emotion_intensity" />
                          <span style="margin-left: 8px">{{
                            voice_config.intensity.max
                            }}</span>
                        </div>
                      </div>
                        </div>
                      </template>

                      <!-- <a-button  v-if="!AISpinging" class="yusu_btn" > -->
                      <a-button v-if="false"  class="yusu_btn" >
                      语速 {{  state.speed }}
                      </a-button>

                    </a-popover>

                    <!-- <a-button v-if="true" class="yusu_btn" :disabled="AISpinging">
                      语速 {{  state.speed }}
                    </a-button> -->

                  
                  </a-col>
                </a-row>
                <a-form-item v-show="state.activeKey == '1'">
                    <a-spin :spinning="AISpinging" >  

                      <!-- 富文本 -->
                      <editor ref="editorRef" :hiddenSSML="hiddenSSML" :voiceData="state.resetData"></editor>

                      <template v-if="false">
                        <a-textarea class="a_textarea" :autosize="{
                            minRows: 15,
                            maxRows: 15,
                          }" show-count :maxlength="maxLen" v-model:value="state.text" placeholder="请输入文案" allow-clear
                           @input="handleInput" 
                           />
                      </template>

                    </a-spin>

                  <div class="mask-text" v-if="state.indicator">
                    <a-spin :indicator="state.indicator" />
                    <div class="mask-box">音频合成中，请稍后...</div>
                  </div>
                  <div class="rule_box">
                    <div class="rule_text"><InfoCircleOutlined style="padding-right:5px;" />提示：{{state.deductionRuleText}}</div>
                    
                    <div class="rule_text_right">
                      <audio-player   v-if="isResultUrl"  class="audio-box" :fileurl="isResultUrl"
                      :playNum="playNum" :index="1" @audioStatus="audioStatus($event)"
                      @setAudio="setAudio()" />

                     <a-popover :title="null" v-if="false">
                      <template #content>
                        试听当前文案的语音效果
                      </template>
                      <!-- 试听 -->
                      <!-- <a-button v-if="!isResultUrl" :disabled="AISpinging" type="primary" ghost style="border-radius: 50px;" 
                      size="small"
                      @click="debouncedplayAutoClick()">
                      <template #icon><customer-service-outlined /></template>
                      试听</a-button> -->

                       <!-- 暂停 / 播放 -->
                       <a-button v-if="isResultUrl" type="primary" ghost style="border-radius: 50px;"  @click="debouncedplayAutoClick()">
                      <template #icon><customer-service-outlined /></template>
                      {{
                      isPlay && isResultUrl ? "暂停" : "播放"
                      }}</a-button>
                     </a-popover>
                     </div>

                  </div>

                  <a-button  class="submit_btn" type="primary" :loading="state.loading || state.indicator || AISpinging"
                    @click="debouncedsubmitCreat">确定合成</a-button>
                </a-form-item>

                <div class="tab_video" v-if="state.activeKey == '2'">
                  <!-- 选择音频 -->
                  <a-form-item v-bind="validateInfos.audio_url" style="">
                    <template #label>
                      {{ videoRequiredData.audio_url?.label }}
                      <a-tooltip>
                        <template #title>
                          {{ videoRequiredData.audio_url?.tip.join("") }}
                        </template>
                        <question-circle-outlined v-if="videoRequiredData.audio_url?.tip" style="margin-left: 5px" />
                      </a-tooltip>
                    </template>
                    <div class="tip_box">
                      <div class="tips_title">音频要求</div>
                      <div class="tips_content">
                        <div class="tips_item">
                          <div class="tips_item_title">文件格式：</div>
                          <div class="tips_item_content">mp3、m4a、wav</div>
                        </div>
                        <div class="tips_item">
                          <div class="tips_item_title">音频时长：</div>
                          <div class="tips_item_content">5秒~3分钟</div>
                        </div>
                        <!-- <div class="tips_item">
                      <div class="tips_item_title">文件大小：</div>
                      <div class="tips_item_content">小于20MB</div>
                    </div>
                    <div class="tips_item">
                      <div class="tips_item_title">采样频率：</div>
                      <div class="tips_item_content">16.000kHz及以上</div>
                    </div> -->
                      </div>
                    </div>

                    <div class="select_voice_style have_voice" v-if="state.audioData">
                      <DeleteOutlined class="del_icon" @click="delVoice"></DeleteOutlined>
                      <!-- 音频暂停状态 -->
                      <PauseCircleOutlined class="voice_icon" v-if="state.voiceState" @click="playVoice">
                      </PauseCircleOutlined>
                      <!-- 音频播放状态 -->
                      <PlayCircleOutlined v-else @click="playVoice" class="voice_icon">
                      </PlayCircleOutlined>
                      <audio ref="voice" @ended="endedChange" @play="onPlayChange" @pause="onPauseChange"
                        :src="state.audioData?.material_url" controls></audio>
                    </div>
                    <div v-else class="select_voice_style select_voice" @click="state.visible = true">
                      <CloudUploadOutlined class="FolderOutlined"></CloudUploadOutlined>
                      <span class="select_tips">点击此处选择或上传您的音频文件</span>
                    </div>
                    <span class="rule_text"><InfoCircleOutlined style="padding-right:5px;" />提示：{{state.deductionRuleText}}</span>
                    <a-button class="submit_btn" type="primary" :loading="state.loading"
                      @click="debouncedsubmitCreat">确定合成</a-button>
                  </a-form-item>
                </div>
              </div>
            </div>
          </div>
        </div>
      </a-form>
    </template>

    <!-- 合成记录 -->
    <template v-else>
<!-- style="padding-left: 120px;" -->
      <a-tabs
      v-model:activeKey="state.compoundTabKey"
      style="height: 100%;"
      >

      <a-tab-pane key="数字人合成" tab="数字人合成">
       
        <div class="list_conent">
        <div class="serch_title">
          <div class="serch_left">
            <div class="serch_item" v-for="(value, key) in state.serchData" :key="key">
              <template v-if="value.type == 'text'">
                <a-input allow-clear @change="(e) => e.type == 'click' && serchChange()" style="width: 229px"
                  v-model:value="state.serchValue[key]" placeholder="请输入任务名称">
                  <template #prefix>
                    <SearchOutlined />
                  </template>
                </a-input>
             
              </template>

              <template v-if="value.type == 'select'">
                <div class="serch_item">
                  <a-select :field-names="{
                      label: 'label',
                      value: 'value',
                      options: 'children',
                    }" style="width: 200px" v-model:value="state.serchValue[key]" :filter-option="false"
                    @change="serchChange" :placeholder="'请选择' + value.label" :options="value.select">
                  </a-select>
                </div>
              </template>

              <!-- {{ key + ':' + state.serchValue[key] }} -->
            </div>

            <div class="serch_item">
              <!-- 日期  -->
              <a-range-picker @change="timeChange" format="YYYY-MM-DD" style="width: 229px" v-model:value="state.time"
                show-time />
            </div>

            <a-button type="primary" :loading="state.serchLoding" @click="getHumanVideoList">查询</a-button>
            <a-button :loading="state.serchLoding" @click="resetSerch">重置</a-button>
          </div>
        </div>

        <!-- 卡片形式的列表 -->

        <div class="cart_list" v-if="state.dataSource.length">
          <div class="cart_item" v-for="item in state.dataSource" :key="item.id">
            <a-tag class="status_tag" :color="statusColor(item.status)">
              <!-- style="font-weight: lighter;" -->
              <span>（{{ item.id }}）</span>
              {{item.status_txt}}
              
                </a-tag>

                <div class="edit_ellip">
                  <a-popover :title="null" placement="bottom">
                    <template #content>
                <div style="display: flex; flex-direction: column;" v-if="item.status == 3 || item.isDel == 1">
                  <!-- :disabled="item.status != 3" -->
                  <a-button type="link"  v-if="item.status == 3"  :loading="item.downloading"
                  @click="handleSave(item, 'down')">下载视频</a-button>
                  <!-- <a-button type="link"  v-if="item.status == 3"
                  @click="listenVoice(item)">试听音频</a-button> -->
                <a-button type="link"   v-if="item.isDel == 1" 
                  @click="delItem(item, 'down')">删除视频</a-button>
   
                  </div>
                </template>
                <div class="ellips_box">
                  <EllipsisOutlined v-if="item.status == 3 || item.isDel == 1"></EllipsisOutlined>
                </div>
                </a-popover>
                </div>

            <div class="cart_main">
              <EyeOutlined v-if="item?.status != 0" @click="toviewVideo(item.video_url)" class="EyeOutlined"></EyeOutlined>

              <a-button 
              v-if="item?.status == 0" 
              :loading="queryResultLoading"
              type="primary" class="query_res" 
              @click.stop="debounceQueryResult(item)">手动查询结果</a-button>

              <template v-if="item?.cover_url">
                    <img :src="item.cover_url" alt="" />
                  </template>
              <template v-else-if="item?.video_url">
                <video :src="item.video_url"></video>
              </template>
              <template v-else>
                <div class="empty_box">
                  <!-- 暂无封面或视频 -->
                  <a-empty description="暂无封面或视频" :image="Empty.PRESENTED_IMAGE_SIMPLE" style="margin: 0 auto"/>
                </div>
              </template>

              <div class="item_name_box">
                <span class="item_name">{{ item.name}}</span>
              </div>
            </div>
            <div class="cart_bottom">
              <div class="msg_box" >
                
                  <a-button  style="padding: 0;" type="link" :disabled="item.status != 3"    
                  @click="creatSubtitle(item)">
                <span style="display: flex; align-items: center; gap: 1px; font-weight: bold;">
                  <FontColorsOutlined style="font-size: 14px;"/>
                  生成字幕
                </span>
                </a-button>

                <a-popover :title="null" placement="top" :getPopupContainer="(target) => {
                  return target.parentNode;
                }">
                  <template #content>
                    <div style="display: flex; flex-direction: column;">
                      <a-button type="link" :disabled="item.status != 3" 
                    @click="handleSave(item, 'material')">保存到素材库</a-button>
                  <a-button type="link" :disabled="item.status != 3" 
                    @click="handleSave(item, 'complete')">保存到成片库</a-button>
                    </div>
                  </template>
                  <a-button :disabled="item.status != 3" type="link" style="padding: 0;">      
                    <span style="display: flex; align-items: center; gap: 2px; font-weight: bold;">
                      <SaveOutlined style="font-size: 14px;"></SaveOutlined>
                  保存到
                </span>
              </a-button>
                </a-popover>

              </div>
            </div>
          </div>
        </div>

        <div style="display: flex; padding: 20px 0;" v-else>
          <a-empty :image="state.simpleImage" style="margin: 0 auto"/>
        </div>

        <div class="smart_clip_content_pagination" v-if="state.dataSource.length > 0">
          <a-pagination :total="state.total" v-model:current="state.page" v-model:pageSize="state.pageSize" show-less-items
            @change="getHumanVideoList" />
        </div>

      </div>
      </a-tab-pane>
      <a-tab-pane key="数字人字幕生成" tab="数字人字幕生成">
        <!-- 数字人字幕生成列表组件 -->
        <subtitleCreatList @viewVideo="toviewVideo" ref="subtitleCreatListRef"></subtitleCreatList>
      </a-tab-pane>
    </a-tabs>


    </template>
  </div>
  <!-- 音频选择 -->
  <ChooseMaterial :isClip="true" material_type="audio" :multiple="false" :visible="state.visible"
    @close="closeChooseMaterial" />

  <!-- 文案仿写组件 -->
  <TextImitationDialog 
  ref="TextImitationDialogRef" 
  :isone_num="true" :isComponents="true"  
  @getTextArr="getTextArr" :TextContent="state.text"
  ></TextImitationDialog>

    <!-- AI扩写 -->
  <AIExpansion ref="aiExpansionRef" :isone_num="true"  :TextContent="state.text" @onConfirm="onConfirmAIExpansion" />

  <!-- 文案库 -->
  <CopyLibraryModal ref="copyLibraryModal" @importSuccess="audioLItemImportSuccess" />
  <AudioSelection :notMixedCutCreat="true" ref="audioSelection" @resetDataChange="resetDataChange" :isTextarea="false">
  </AudioSelection>
  <!-- 视频文件夹 -->
  <!-- :visible="state.saveVisible" -->
  <MaterialsModule ref="materials" :requestType="true" jobCategory="videoSplit" :data="state.materialData"
    :material_type="'video'" :isFlaking="state.isFlaking" :visible="state.saveVisible" @selfRequest="selfRequest"
    @onCancel="onCancel" />
  <!-- 下一步弹窗 -->
  <creatNextDialog ref="creatNextDialogRef" @timerOver="timerOver"></creatNextDialog>
  <!-- 保存到素材弹框 -->
  <!-- <MaterialsModule :visible="state.visibleMaterials" :data="materialData" @onCancel="visibleMaterials = false"
    @onSuccess="state.visibleMaterials = false" /> -->
  <!-- 选择合成模型 -->

  <!-- <creatTypeDialog ref="creatTypeDialogRef" @isSubmit="creatTypeDialogSubmit"></creatTypeDialog> -->
  <!-- 试听音频 -->
  <listenVoiceDialog ref="listenVoiceDialogRef"></listenVoiceDialog>

  <!-- 充值弹窗 -->
  <vipModal ref="vipModalRef" :visible="vipVisible" @close="vipVisible = false"></vipModal>

  <!-- 生成字幕弹窗 -->
  <subtitleCreatDialog ref="subtitleCreatDialogRef" @openSubtitleCreat="openSubtitleCreat"></subtitleCreatDialog>

    <!-- 视频预览弹窗 -->
    <a-modal :style="{ border: 'none'}" v-model:visible="state.viewVisible"
      :maskClosable="true" :width="800"
      :zIndex="1000"  :centered="false"
      :closable="true" :keyboard="false">
      <template #title>
        <slot name="title">
            <span>查看视频</span>
        </slot>
      </template>

      <div class="view_content">
        <video :src="state.videoUrl" controls autoplay ref="videoRef" class="is_video">
          </video>
      </div>

      <template #footer>
        <a-button type="primary" @click="state.viewVisible = false">关闭</a-button>
      </template>
    </a-modal>
</template>

<style lang="less" scoped>
:deep(.ss-form-vertical .ss-form-item-label > label) {
  width: 100%;
}

:deep(.ss-form-item) {
  margin-bottom: 5px;
}

:deep(.ss-tabs-nav) {
  margin-bottom: 0;
}

// :deep(.ss-input) {
//   background-color: rgb(245, 245, 245);
//   border: none;
// }

:deep(.ss-input) {
  resize: none;
  // padding-right: 14px;

  &::-webkit-scrollbar {
    height: 5px;
    /* 滚动条的高度 */
    width: 8px;
    display: none;
  }
}

:deep(.ss-tabs-content) {
  height: 100%;
}

// 视频预览弹窗样式
.view_content{
  width: 100%;
    height: 500px;
    display: flex;
    justify-content: center;
    background: #000000;

    video {
        height: 100%;
        width: 100%;
        background: rgb(223, 223, 223);
    }
}


.AIdigitalHumanCreatVideo {
  @radius: 8px;
  @pd: 15px;
  padding: 10px;
  min-width: 1250px;
  height: 100%;
  overflow: hidden;

  :deep(.ss-tabs > .ss-tabs-nav .ss-tabs-nav-wrap) {
    // background: #fff;
    padding-left: 5px;
  }

  :deep(.ss-tabs-top){
    padding-bottom: 0!important;
  }

  .list_conent {
    height: 100%;
    // overflow-y: auto;
    padding-bottom: 50px;

    display: flex;
    flex-direction: column;
    .table {
      .video_cart {
        height: 90px;
        width: 90px;
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;
        cursor: pointer;
        transition: all 0.3s;
        border: 1px solid transparent;
        border-radius: 5px;

        &:hover {
          border-color: var(--ss-primary-color-hover);

          .EyeOutlined {
            opacity: 1;
          }

          &::after {
            opacity: 1;
          }

          // & .bottom_box {
          //   opacity: 1;
          // }
        }

        &::after {
          content: "";
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background: #0000004b;
          opacity: 0;
          transition: all 0.3s;
        }

        .EyeOutlined {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          transition: all 0.3s;
          opacity: 0;
          font-size: 22px;
          color: #fff;
          z-index: 2;

          &:hover {
            color: var(--ss-primary-color-hover);
          }
        }

        img {
          height: 100%;
          width: auto;
        }

        video {
          height: 100%;
          width: auto;
        }
      }
    }

    // table 头部的筛选
    .serch_title {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      margin-top: 10px;
      margin-bottom: 20px;

      .serch_left {
        display: flex;
        gap: 0 10px;

        .serch_item {
          display: flex;
          justify-content: center;
          align-items: center;

          .left_prefix {
            padding: 0 25px;
            background-color: #ffffff;
            line-height: 30px;
            border: 1px solid #d9d9d9;
            border-right: none;
          }
        }
      }
    }

    // table 列表
    .cart_list{
      display: flex;
      flex-wrap: wrap;
      align-items: flex-start;
      gap: 20px 20px;
      overflow-y: auto;
      overflow-x: hidden;
      &::-webkit-scrollbar {
            width: 8px; /* 滚动条的宽度 */
            height: 10px; /* 滚动条的高度，垂直滚动条可能用得上 */
        }
        &::-webkit-scrollbar-thumb {
            background: #888; /* 滑块的背景颜色 */
            border-radius: 10px; /* 滑块的圆角 */

        }
      

      .cart_item{
        background-color: #fff;
        border: 1px solid #eee;
        position: relative;
        // max-width: 190px;

        .status_tag{
          position: absolute;
          left: 5px;
          top: 5px;
          z-index: 1;
          font-size: 12px;
          font-weight: bold;
        }
        .edit_ellip{
          position: absolute;
          z-index: 3;
          right: 5px;
          top: 5px;
          font-size: 28px;
          color: #fff;
          line-height: 1;
          font-weight: bold;
          cursor: pointer;

          .ellips_box{
            background: #0000004b;
            padding: 0 5px;
            border-radius: 8px;
          }
        }
        .cart_main{
          height: 280px;
          width: 190px;
          cursor: pointer;
          position: relative;

                  // name 遮罩层
        .item_name_box{
          position: absolute;
          bottom: 0;
          left: 0;
          width: 100%;
          padding: 2px 5px;
          background: #0000004b;
          .item_name{
              color: #fff;
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-line-clamp: 1;
              -webkit-box-orient: vertical;
              width: auto;
            }
        }

          img{
            height: 100%;
            width: 100%;
            object-fit: cover;
          }
          video{
            height: 100%;
            width: 100%;
          }
          .empty_box{
            height: 100%;
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            // background-color: #00000017;
          }

          &::after{
          content: '';
          position: absolute;
          left: 0;
          top: 0;
          z-index: 2;
          background-color: transparent;
          opacity: 0;
          transition: all .3s;
          height: 100%;
          width: 100%;
        }
          &:hover{
          &::after{
            background-color: #00000056;
            opacity: 1;
          }

          .EyeOutlined{
            opacity: 1;
          }
          .query_res{
            opacity: 1;
          }
        }

        .EyeOutlined{
          position: absolute;
          z-index: 3;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          color: #fff;
          transition: all .3s;
          opacity: 0;
          font-size: 30px;
          &:hover{
            color: var(--ss-primary-color-hover);
          }
        }

        .query_res {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          transition: all 0.3s;
          opacity: 0;
          z-index: 3;
        }

        }
        .cart_bottom{
          width: 100%;
          background-color: #fff;
          padding: 5px 5px;
          font-weight: bold;
          border-top: 1px solid #eee;

          .msg_box{
            display: flex;
            justify-content: space-between;
            align-items: center;


          }
        }
      }
    }

      // 分页
  .smart_clip_content_pagination {
    display: flex;
    margin-top: 20px;
    justify-content: flex-end;
  }

  }

  .title_box {
    display: flex;
    justify-content: center;
    padding: 10px 15px;
    background-color: #fff;
    border-radius: @radius;

    .step_box {
      height: 100%;
      width: 25%;
    }
  }

  .content_box {
    flex: 1;
    height: 100%;
    display: flex;
    gap: 15px;
    padding-top: 10px;
    padding-bottom:40px;
    overflow: hidden;

    .right_box {
      border-radius: @radius;
      flex: 1;
      background-color: #ffffff;
      // height: ceil(100% - 10px);
      height: 100%;
      position: relative;
      overflow-y: auto;

      &::-webkit-scrollbar {
            display: none;
        }

      .tab_text {
        height: 100%;
        display: flex;
        gap: 20px;
        padding: @pd;
        padding-top: 0;

        .tab_text_left {
          flex: 1;
          display: flex;
          flex-direction: column;
          gap: 15px;

          .name_box {
            display: flex;
            align-items: center;

            p {
              width: 40px;
              margin: 0;
            }
          }

          .a_textarea {
            resize: none;
          }

          .mask-text {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(255, 255, 255, 0.5);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;

            .mask-box {
              width: 176px;
              height: 62px;
              color: #2878ff;
              display: flex;
              align-items: center;
              justify-content: center;
              font-size: 12px;
            }
          }
        }

        .tab_text_right {
          // flex: 1;
          min-width: 537px;
          width: 46.5%;
        }
      }

      .tab_video {
        display: flex;
        flex-direction: column;
        gap: 20px;
        height: 100%;
        // padding: 0 10%;
        padding-top: 0;

        .tip_box {
          background-color: #f6f7f9;
          display: flex;
          flex-direction: column;
          padding: 5px 12px;
          margin-bottom: 15px;

          .tips_title {
            font-weight: 700;
          }

          .tips_content {
            display: flex;
            flex-wrap: wrap;
            // justify-content: space-between;
            gap: 5px 20px;

            .tips_item {
              display: flex;

              .tips_item_title {
                color: #333333;
              }

              .tips_item_content {
                color: #888888;
              }
            }
          }
        }

        // 选择音频容器公共样式
        .select_voice_style {
          height: 300px;
          width: 100%;
          border-radius: 8px;
          border: 1px solid #c0c0c0;
          display: flex;

          &:hover {
            border-color: var(--ss-primary-color-hover);
            color: var(--ss-primary-color-hover);
          }
        }

        // 没有音频的样式
        .select_voice {
          cursor: pointer;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          color: #666666;
          transition: all 0.3s;

          .FolderOutlined {
            font-size: 30px;
          }
        }

        // 选择了音频的样式
        .have_voice {
          // flex-direction: column;
          // align-items: center;
          // justify-content: space-between;
          padding: 15px;
          position: relative;
          transition: all 0.3s;

          .voice_icon {
            color: #666666;
            cursor: pointer;
            font-size: 60px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);

            &:hover {
              color: var(--ss-primary-color-hover);
            }
          }

          .del_icon {
            color: #666666;
            cursor: pointer;
            position: absolute;
            right: 10px;
            top: 10px;
            font-size: 23px;

            &:hover {
              color: var(--ss-error-color);
            }
          }

          audio {
            width: calc(100% - 30px);
            position: absolute;
            bottom: 15px;
            left: 15px;
          }
        }
      }

      // 扣费规则
    .rule_text{
      color: #666;
      font-size: 14px;
      margin-top: 10px;
      display: inline-block;

    }
      // 提交按钮
      .submit_btn {
        // width: calc(100% - 150px);
        width: 100%;
        display: block;
        margin: 20px auto;
        margin-top: 10px;
        // position: absolute;
        // bottom: 25%;
        // left: 75px;
      }
    }

    .left_box {
      width: 550px;
      // flex: 1;
      min-width: 550px;
      background-color: #fff;
      display: flex;
      flex-direction: column;
      border-radius: @radius;
      padding: @pd;
      overflow-y: auto;

      h2 {
        font-size: 16px;
        font-weight: 600;
      }

      .list_box {
        flex: 1;
        display: flex;
        flex-wrap: wrap;
        align-content: start;
        gap: 15px;
        overflow-y: auto;
        padding-bottom: 40px;
        padding-top: 10px;

        &::-webkit-scrollbar {
          width: 5px;
          /* 滚动条的宽度 */
          height: 10px;
          /* 滚动条的高度，垂直滚动条可能用得上 */
        }

        &::-webkit-scrollbar-thumb {
          background: #c4c4c4;
          /* 滑块的背景颜色 */
          border-radius: 10px;
          /* 滑块的圆角 */
        }

        .list_item {
          height: 130px;
          width: 247px;
          border-radius: @radius;
          overflow: hidden;
          position: relative;
          cursor: pointer;
          text-align: center;
          background: #000;

          // 遮罩
          &::after {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            width: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            transition: all 0.3s;
            opacity: 0;
          }

          &:hover {
            &::after {
              opacity: 1;
            }

            .icon_PlayCircleOutlined {
              opacity: 1;
            }
          }

          img {
            // width: auto;
            width: 100%;
            height: 100%;
            object-fit: cover;
          }

          .check_box {
            position: absolute;
            top: 5px;
            right: 5px;
            z-index: 3;
          }

          .icon_PlayCircleOutlined {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            font-size: 36px;
            color: #fff;
            transition: all 0.3s;
            opacity: 0;
            z-index: 2;

            &:hover {
              color: var(--ss-primary-color-hover);
            }
          }

          .mask_name {
            padding: 0 10px;

            .is_span {
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-line-clamp: 1;
              -webkit-box-orient: vertical;
              width: auto;
            }

            // 一行显示
          }

          .mask-box {
            position: absolute;
            width: 100%;
            height: 30px;
            background: rgba(0, 0, 0, 0.5);
            bottom: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            font-size: 13px;
          }
        }

        .empty-box {
          width: 100%;
          flex-direction: column;
          text-align: center;
          justify-content: center;
        }
      }
    }
  }
}

.yusu_btn {
  margin-left: 20px;
}

.config_cart {
      // margin-top: 32px;

      .slider_box {
        display: flex;
        align-items: center;

        span {
          font-size: 12px;
          color: #727477;
        }

        .slider {
          flex: 1;
        }
      }
}

.yinse_vonfig {
  width: 300px;
  position: relative;
}

.rule_text_right {
  margin-right: 80px;
  display: flex;
  align-items: center;
}

.rule_box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 5px;
}


.reset_btn {
  position: absolute;
  top: 0px;
  right: 0px;
  transition: opacity 0.3s;
  cursor: pointer;
  font-size: 16px;
}
</style>
